package com.yytek.am.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson2.JSON;
import com.yytek.am.constants.AkkaConstants;
import com.yytek.am.constants.MessageType;
import com.yytek.am.core.rule.EventRule;
import com.yytek.am.domain.FmDefRlobject;
import com.yytek.am.domain.FmRuleClear;
import com.yytek.am.domain.FmRuleGenerate;
import com.yytek.am.mapper.FmDefRlobjectMapper;
import com.yytek.am.mapper.FmRuleClearMapper;
import com.yytek.am.mapper.FmRuleGenerateMapper;
import com.yytek.common.client.net.IotMqttClient;
import com.yytek.common.core.utils.DateUtils;
import com.yytek.common.security.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.yytek.am.mapper.FmDefMapper;
import com.yytek.am.domain.FmDef;
import com.yytek.am.service.IFmDefService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;


/**
 * 告警定义Service业务层处理
 * 
 * @author yytek-iot
 * @date 2022-10-10
 */
@Service
public class FmDefServiceImpl implements IFmDefService 
{
    @Resource
    private FmDefMapper fmDefMapper;
    @Resource
    private FmDefRlobjectMapper fmDefRlobjectMapper;
    @Resource
    IotMqttClient iotMqttClient;
    @Resource
    private FmRuleGenerateMapper fmRuleGenerateMapper;
    @Resource
    private FmRuleClearMapper fmRuleClearMapper;
    /**
     * 查询告警定义
     * 
     * @param id 告警定义主键
     * @return 告警定义
     */
    @Override
    public FmDef selectFmDefById(Long id)
    {
        return fmDefMapper.selectFmDefById(id);
    }

    /**
     * 查询告警定义列表
     * 
     * @param fmDef 告警定义
     * @return 告警定义
     */
    @Override
    public List<FmDef> selectFmDefList(FmDef fmDef)
    {
        return fmDefMapper.selectFmDefList(fmDef);
    }

    /**
     * 新增告警定义
     * 
     * @param fmDef 告警定义
     * @return 结果
     */
    @Override
    public int insertFmDef(FmDef fmDef)
    {
        fmDef.setCreateTime(DateUtils.getNowDate());
        fmDef.setUpdateTime(DateUtils.getNowDate());
        //添加创建人信息
        String userId = SecurityUtils.getUserId().toString();
        fmDef.setOperator(userId);
        Integer reNum = fmDefMapper.insertFmDef(fmDef);
        if(reNum != null && reNum >0){
            //发送mqtt，akka接收变更
            sendAkkaMqttDefChange(AkkaConstants.EventRuleUpdateType.UPDATE,fmDef);
        }
        return reNum;
    }

    /**
     * 发送mqtt，akka接收变更告警规则定义
     *
     * @param type 新增，修改,删除类型
     * @param fmDef
     */
    public void sendAkkaMqttDefChange(int type, FmDef fmDef) {
        EventRule eventRule = new EventRule();
        eventRule.setId(fmDef.getId());
        eventRule.setProjectId(fmDef.getProjectId());
        eventRule.setProjectName(fmDef.getProjectName());
        eventRule.setCreateTime(fmDef.getCreateTime().getTime());
        eventRule.setUpdateTime(fmDef.getUpdateTime().getTime());
        eventRule.setKpiName(fmDef.getKpiName());
        eventRule.setLabel(fmDef.getLabel());
        eventRule.setLevel(fmDef.getLevel().intValue());
        eventRule.setTitle(fmDef.getTitle());
        eventRule.setContent(fmDef.getContent());
        eventRule.setSearchIndex(fmDef.getSearchIndex());
        eventRule.setSubIndex(fmDef.getSubIndex());
        eventRule.setOperator(fmDef.getOperator());
        eventRule.setStatus(fmDef.getStatus());
        //查询关联定义信息
        FmDefRlobject cx = new FmDefRlobject();
        cx.setAlarmDefineId(fmDef.getId());
        List<FmDefRlobject> fmDefRlobjectList = fmDefRlobjectMapper.selectFmDefRlobjectList(cx);
        Map<Long, List<FmDefRlobject>> fmDefRlobjectMap = new HashMap<>();
        if(CollectionUtil.isNotEmpty(fmDefRlobjectList)){
            fmDefRlobjectMap = fmDefRlobjectList.stream().collect(Collectors.groupingBy(item -> item.getAlarmDefineId()));
        }
        Set<String> rlObjects = new HashSet<>();
        if (fmDefRlobjectMap.containsKey(fmDef.getId())) {
            for (FmDefRlobject fmDefRlobject : fmDefRlobjectMap.get(fmDef.getId())
            ) {
                rlObjects.add(fmDefRlobject.getRlObjectId());
            }
        }
        eventRule.setRlObjects(rlObjects);
        String json = JSON.toJSONString(eventRule);
        iotMqttClient.publish(MessageType.EventRule.EVENT_RULE.replace("+",
                String.valueOf(type)),json);
    }

    /**
     * 修改告警定义
     * 
     * @param fmDef 告警定义
     * @return 结果
     */
    @Override
    public int updateFmDef(FmDef fmDef)
    {
        //添加创建人信息
        String userId = SecurityUtils.getUserId().toString();
        fmDef.setOperator(userId);
        fmDef.setUpdateTime(DateUtils.getNowDate());
        Integer num = fmDefMapper.updateFmDef(fmDef);
        //发送mqtt，akka接收变更
        FmDef sendFmDef = selectFmDefById(fmDef.getId());
        if(sendFmDef != null){
            sendAkkaMqttDefChange(AkkaConstants.EventRuleUpdateType.UPDATE,sendFmDef);
        }
        return num;
    }

    /**
     * 批量删除告警定义
     * 
     * @param ids 需要删除的告警定义主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteFmDefByIds(Long[] ids)
    {
        if (ids.length > 0){
            for (int i = 0; i < ids.length; i++) {
                Long id = ids[i];
                FmDef fmDef = selectFmDefById(id);
                if(fmDef != null){
                    //发送mqtt，akka接收变更
                    sendAkkaMqttDefChange(AkkaConstants.EventRuleUpdateType.DELETE,fmDef);
                    //删除告警定义关联规则
                    deleteRefAllRuleByDefId(id);
                }
            }
        }
        Integer num = fmDefMapper.deleteFmDefByIds(ids);

        return num;
    }

    /**
     * 删除告警定义关联规则
     * @param id
     */
    private void deleteRefAllRuleByDefId(Long id) {
        //删除清除规则
        fmRuleClearMapper.deleteByDefId(id);
        //删除生成规则
        fmRuleGenerateMapper.deleteByDefId(id);
    }

    /**
     * 删除告警定义信息
     * 
     * @param id 告警定义主键
     * @return 结果
     */
    @Override
    public int deleteFmDefById(Long id)
    {
        FmDef fmDef = selectFmDefById(id);
        //发送mqtt，akka接收变更
        sendAkkaMqttDefChange(AkkaConstants.EventRuleUpdateType.DELETE,fmDef);
        Integer num = fmDefMapper.deleteFmDefById(id);
        return num;
    }
}
